home *** CD-ROM | disk | FTP | other *** search
/ Aminet 28 / Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso / Aminet / game / shoot / athrust.lha / AmigaThrust / src / things.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-09-05  |  16.4 KB  |  797 lines

  1.  
  2. /* Written by Peter Ekberg, peda@lysator.liu.se */
  3.  
  4. #ifdef HAVE_CONFIG_H
  5. # include "config.h"
  6. #endif
  7.  
  8. #ifdef HAVE_UNISTD_H
  9. # include <unistd.h>
  10. #endif
  11.  
  12. #ifdef HAVE_VALUES_H
  13. # include <values.h>
  14. #else
  15. # include <limits.h>
  16. # define MAXINT  INT_MAX
  17. # define MAXLONG LONG_MAX
  18. #endif
  19.  
  20. #include <stdlib.h>
  21. #include <math.h>
  22.  
  23. #include "thrust_t.h"
  24. #include "things.h"
  25. #include "fast_gr.h"
  26. #include "graphics.h"
  27. #include "thrust.h"
  28.  
  29. #ifdef HAVE_SOUND
  30. # include "soundIt.h"
  31.  
  32. # define CHAN_1 0
  33. # define CHAN_2 1
  34. # define CHAN_3 2
  35. # define CHAN_4 3
  36.  
  37. # define SND_BOOM   0
  38. # define SND_BOOM2  1
  39. # define SND_HARP   2
  40. # define SND_THRUST 3
  41. # define SND_ZERO   4
  42. #endif
  43.  
  44. word nrthings=0;
  45. word nrsliders=0;
  46. word nrbarriers=0;
  47. word nrrestartpoints=0;
  48.  
  49. bullet bullets[maxbullets];
  50. fragment fragments[maxfragments];
  51. thing things[maxthings];
  52. slider sliders[maxsliders];
  53. barrier barriers[maxbarriers];
  54. restartpoint restartpoints[maxrestartpoints];
  55.  
  56. word powerplant;
  57. word ppx,ppy,ppcount;    /* Power Plant variables */
  58. word ppblip;
  59.  
  60. void
  61. newslider(x, y, type)
  62.      int x, y, type;
  63. {
  64.   sliders[nrsliders].x1=x;
  65.   sliders[nrsliders].y1=y;
  66.   sliders[nrsliders].type=type;
  67.   sliders[nrsliders].dir=type%3;
  68.   sliders[nrsliders].match=0;
  69.   sliders[nrsliders].active=0;
  70.   sliders[nrsliders++].next=NULL;
  71. }
  72.  
  73. int
  74. majorbutton(int button)
  75. {
  76.   if(((buttondata *)things[button].data)->major==-1)
  77.     return(button);
  78.   else
  79.     return(((buttondata *)things[button].data)->major);
  80. }
  81.  
  82. void
  83. newthing(int x, int y, int px, int py, int type, void *data)
  84. {
  85.   int life;
  86.  
  87.   switch(type) {
  88.   case 1:       /* Fuel */
  89.     life=140;
  90.     break;
  91.   default:
  92.     life=2;
  93.   }
  94.   things[nrthings].alive=life;
  95.   things[nrthings].x=x;
  96.   things[nrthings].y=y;
  97.   things[nrthings].px=px;
  98.   things[nrthings].py=py;
  99.   things[nrthings].type=type;
  100.   things[nrthings].data=data;
  101.   things[nrthings++].score=0;
  102. }
  103.  
  104. void
  105. animatesliders(void)
  106. {
  107.   slider *s=sliders;
  108.   int i;
  109.  
  110.   for(i=0; i<nrsliders; i++, s++)
  111.     if(s->active) {
  112.       switch(s->stage) {
  113.       case 0:
  114.     if(!(s->count&7)) {
  115.       switch(s->type) {
  116.       case 2:
  117.         if(s->count==0) {
  118.           writeblock(s->x1-(s->count>>3),   s->y1, 'x');
  119.           writeblock(s->x1-(s->count>>3)-1, s->y1, 136);
  120.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'q');
  121.         }
  122.         else if(s->count==8) {
  123.           writeblock(s->x1-(s->count>>3),   s->y1, 'w');
  124.           writeblock(s->x1-(s->count>>3)-1, s->y1, 'r');
  125.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'q');
  126.         }
  127.         else {
  128.           writeblock(s->x1-(s->count>>3),   s->y1, ' ');
  129.           writeblock(s->x1-(s->count>>3)-1, s->y1, 'r');
  130.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'q');
  131.         }
  132.         break;
  133.       case 5:
  134.         if(s->count==0) {
  135.           writeblock(s->x1-(s->count>>3)  , s->y1, 138);
  136.           writeblock(s->x1-(s->count>>3)-1, s->y1, 139);
  137.         }
  138.         else if(s->count==8) {
  139.           writeblock(s->x1-(s->count>>3)  , s->y1, 141);
  140.           writeblock(s->x1-(s->count>>3)-1, s->y1, 134);
  141.         }
  142.         else {
  143.           writeblock(s->x1-(s->count>>3)  , s->y1, 135);
  144.           writeblock(s->x1-(s->count>>3)-1, s->y1, 134);
  145.         }
  146.         break;
  147.       case 7:
  148.         writeblock(s->x1+(s->count>>3), s->y1, 'y');
  149.         break;
  150.       case 8:
  151.         writeblock(s->x1-(s->count>>3), s->y1, '|');
  152.         break;
  153.       case 10:
  154.         writeblock(s->x1, s->y1+(s->count>>3), 129);
  155.         break;
  156.       case 11:
  157.         writeblock(s->x1, s->y1-(s->count>>3), 128);
  158.         break;
  159.       }
  160.     }
  161.     else if(!(s->count&3)) {
  162.       switch(s->type) {
  163.       case 2:
  164.         if(s->count==4) {
  165.           writeblock(s->x1-(s->count>>3)-1, s->y1, 137);
  166.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'n');
  167.         }
  168.         else {
  169.           writeblock(s->x1-(s->count>>3)-1, s->y1, 'o');
  170.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'n');
  171.         }
  172.         break;
  173.       case 5:
  174.         if(s->count==4) {
  175.           writeblock(s->x1-(s->count>>3),   s->y1, 133);
  176.           writeblock(s->x1-(s->count>>3)-1, s->y1, 140);
  177.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'u');
  178.         }
  179.         else if(s->count==12) {
  180.           writeblock(s->x1-(s->count>>3),   s->y1, 132);
  181.           writeblock(s->x1-(s->count>>3)-1, s->y1, 'v');
  182.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'u');
  183.         }
  184.         else {
  185.           writeblock(s->x1-(s->count>>3),   s->y1, ' ');
  186.           writeblock(s->x1-(s->count>>3)-1, s->y1, 'v');
  187.           writeblock(s->x1-(s->count>>3)-2, s->y1, 'u');
  188.         }
  189.         break;
  190.       case 7:
  191.         writeblock(s->x1+(s->count>>3), s->y1, ' ');
  192.         break;
  193.       case 8:
  194.         writeblock(s->x1-(s->count>>3), s->y1, ' ');
  195.         break;
  196.       case 10:
  197.         writeblock(s->x1, s->y1+(s->count>>3), ' ');
  198.         break;
  199.       case 11:
  200.         writeblock(s->x1, s->y1-(s->count>>3), ' ');
  201.         break;
  202.       }
  203.     }
  204.     s->count++;
  205.     if(s->count >= ((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1) {
  206.       s->count=0;
  207.       s->stage=1;
  208.     }
  209.     break;
  210.       case 1:
  211.     s->count++;
  212.     if(s->count>500) {
  213.       s->count=0;
  214.       s->stage=2;
  215.     }
  216.     break;
  217.       case 2:
  218.     if(!(s->count&7)) {
  219.       switch(s->type) {
  220.       case 2:
  221.         if(s->count>>3==s->x1-s->x2) {
  222.           writeblock(s->x2+(s->count>>3)-1, s->y1, 136);
  223.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'q');
  224.         }
  225.         else {
  226.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'r');
  227.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'q');
  228.         }
  229.         break;
  230.       case 5:
  231.         if(s->count>>3==s->x1-s->x2) {
  232.           writeblock(s->x2+(s->count>>3)  , s->y1, 138);
  233.           writeblock(s->x2+(s->count>>3)-1, s->y1, 139);
  234.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  235.         }
  236.         else if(s->count>>3==s->x1-s->x2-1) {
  237.           writeblock(s->x2+(s->count>>3)  , s->y1, 141);
  238.           writeblock(s->x2+(s->count>>3)-1, s->y1, 134);
  239.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  240.         }
  241.         else {
  242.           writeblock(s->x2+(s->count>>3)  , s->y1, 135);
  243.           writeblock(s->x2+(s->count>>3)-1, s->y1, 134);
  244.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  245.         }
  246.         break;
  247.       case 7:
  248.         writeblock(s->x2-(s->count>>3), s->y1, 'y');
  249.         break;
  250.       case 8:
  251.         writeblock(s->x2+(s->count>>3), s->y1, '|');
  252.         break;
  253.       case 10:
  254.         writeblock(s->x1, s->y2-(s->count>>3), 129);
  255.         break;
  256.       case 11:
  257.         writeblock(s->x1, s->y2+(s->count>>3), 128);
  258.         break;
  259.       }
  260.     }
  261.     else if(!(s->count&3)) {
  262.       switch(s->type) {
  263.       case 2:
  264.         if(s->count>>3==s->x1-s->x2) {
  265.           writeblock(s->x2+(s->count>>3)  , s->y1, 'p');
  266.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'p');
  267.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  268.         }
  269.         else if(s->count>>3==s->x1-s->x2-1) {
  270.           writeblock(s->x2+(s->count>>3)  , s->y1, 137);
  271.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'n');
  272.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  273.         }
  274.         else {
  275.           writeblock(s->x2+(s->count>>3)  , s->y1, 'o');
  276.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'n');
  277.           writeblock(s->x2+(s->count>>3)-2, s->y1, 'p');
  278.         }
  279.         break;
  280.       case 5:
  281.         if(s->count>>3==s->x1-s->x2) {
  282.           writeblock(s->x2+(s->count>>3)  , s->y1, 'p');
  283.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'p');
  284.         }
  285.         else if(s->count>>3==s->x1-s->x2-1) {
  286.           writeblock(s->x2+(s->count>>3)  , s->y1, 140);
  287.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'u');
  288.         }
  289.         else {
  290.           writeblock(s->x2+(s->count>>3)  , s->y1, 'v');
  291.           writeblock(s->x2+(s->count>>3)-1, s->y1, 'u');
  292.         }
  293.         break;
  294.       case 7:
  295.         writeblock(s->x2-(s->count>>3), s->y1, 'p');
  296.         break;
  297.       case 8:
  298.         writeblock(s->x2+(s->count>>3), s->y1, 'p');
  299.         break;
  300.       case 10:
  301.         writeblock(s->x1, s->y2-(s->count>>3), 'p');
  302.         break;
  303.       case 11:
  304.         writeblock(s->x1, s->y2+(s->count>>3), 'p');
  305.         break;
  306.       }
  307.     }
  308.     s->count++;
  309.     if(s->count >= ((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1)
  310.       s->active=0;
  311.     break;
  312.       }
  313.     }
  314. }
  315.  
  316. void
  317. startupsliders(int button)
  318. {
  319.   slider *s;
  320.  
  321.   s=((buttondata *)things[button].data)->sliders;
  322.  
  323.   while(s) {
  324.     if(s->active) {
  325.       switch(s->stage) {
  326.       case 1:
  327.     s->count=0;
  328.     break;
  329.       case 2:
  330.     s->count=(((abs(s->x1-s->x2)+abs(s->y1-s->y2)+1) << 3)-1) - s->count-7;
  331.     if(s->count<0)
  332.       s->count=0;
  333.     s->stage=0;
  334.     break;
  335.       default:
  336.     break;
  337.       }
  338.     }
  339.     else {
  340. #ifdef HAVE_SOUND
  341.       if(play_sound)
  342.     Snd_effect(SND_HARP, CHAN_3);
  343. #endif
  344.       s->active=1;
  345.       s->stage=0;
  346.       s->count=0;
  347.     }
  348.     s=s->next;
  349.   }
  350. }
  351.  
  352. restartpoint *
  353. atbarrier(word bx, word by)
  354. {
  355.   int i;
  356.  
  357.   for(i=0; i<nrbarriers; i++)
  358.     if((barriers[i].x==bx) && (barriers[i].y==by))
  359.       return(barriers[i].restart);
  360.   return(NULL);
  361. }
  362.  
  363. void
  364. deletething(thing *tp)
  365. {
  366.   int tx, ty, i, j;
  367.  
  368.   tx=(*tp).px;
  369.   ty=(*tp).py;
  370.   (*tp).alive=0;
  371.  
  372.   switch((*tp).type)
  373.     {
  374.     case 1:        /* Fuel */
  375.       for(i=0; i<2; i++)
  376.     for(j=0; j<2; j++)
  377.       writeblock(tx+i, ty+j, 32);
  378.       break;
  379.     case 2:        /* Power Plant */
  380.       if(powerplant) {
  381.     powerplant=0;
  382.     countdown=1000;
  383.     for(i=0; i<2; i++)
  384.       for(j=0; j<2; j++)
  385.         writeblock(tx+i, ty+j, 32);
  386.       }
  387.       if(countdown)
  388.     (*tp).alive=1;
  389.       else {
  390.     killallthings();
  391. #ifdef HAVE_SOUND
  392.     if(play_sound)
  393.       Snd_effect(SND_BOOM2, CHAN_4);
  394. #endif
  395.     for(i=0; i<3; i++)
  396.       for(j=0; j<3; j++)
  397.         writeblock(tx+i, ty+j, 32);
  398.     explodething(tp);
  399.       }
  400.     break;
  401.     case 3:             /* Bunkers */
  402.       writeblock(tx,   ty,   32);
  403.       writeblock(tx+1, ty,   32);
  404.       writeblock(tx+2, ty,   32);
  405.       writeblock(tx+2, ty+1, 32);
  406.       break;
  407.     case 4:
  408.       writeblock(tx,   ty+1, 32);
  409.       writeblock(tx,   ty,   32);
  410.       writeblock(tx+1, ty,   32);
  411.       writeblock(tx+2, ty,   32);
  412.       break;
  413.     case 5:
  414.       writeblock(tx,   ty+1, 32);
  415.       writeblock(tx+1, ty+1, 32);
  416.       writeblock(tx+2, ty+1, 32);
  417.       writeblock(tx+2, ty,   32);
  418.       break;
  419.     case 6:
  420.       writeblock(tx,   ty,   32);
  421.       writeblock(tx,   ty+1, 32);
  422.       writeblock(tx+1, ty+1, 32);
  423.       writeblock(tx+2, ty+1, 32);
  424.       break;
  425.     case 7:
  426.     case 8:
  427.       writeblock(tx,   ty,   32);
  428.       writeblock(tx,   ty+1, 32);
  429.       break;
  430.     }
  431. }
  432.  
  433. void
  434. newbullet(word x, word y, int vx, int vy, word dir, int owner)
  435. {
  436.   static word nr=0;
  437.  
  438. #ifdef HAVE_SOUND
  439.   if(play_sound)
  440.     Snd_effect(SND_BOOM, CHAN_2);
  441. #endif
  442.   bullets[nr].life=60;
  443.   bullets[nr].x=x;
  444.   bullets[nr].y=y;
  445.   bullets[nr].vx=vx;
  446.   bullets[nr].vy=vy;
  447.   bullets[nr].dir=dir;
  448.   bullets[nr++].owner=owner;
  449.  
  450.   if(nr==maxbullets)
  451.     nr=0;
  452. }
  453.  
  454. void
  455. movebullets(void)
  456. {
  457.   int l;
  458.   bullet *bulletptr;
  459.  
  460.   for(l=0, bulletptr=bullets; l<maxbullets; l++, bulletptr++)
  461.     if((*bulletptr).life) {
  462.       (*bulletptr).life--;
  463.       (*bulletptr).x=((*bulletptr).x+(lenx<<6)+(*bulletptr).vx) % (lenx<<6);
  464.       (*bulletptr).y=((*bulletptr).y+(leny<<6)-(*bulletptr).vy) % (leny<<6);
  465.     }
  466. }
  467.  
  468. word
  469. crashtype(word type)
  470. {
  471.   switch(type) {
  472.   case 1:      /* Fuel */
  473.   case 2:      /* Power Plant */
  474.   case 3:      /* 3-6 Bunkers */
  475.   case 4:
  476.   case 5:
  477.   case 6:
  478.   case 7:      /* 7-8 Buttons */
  479.   case 8:
  480.     return(4);
  481.   }
  482.   return(0);
  483. }
  484.  
  485. int
  486. inloadcontact(int x, int y)
  487. {
  488.   int dx, dy;
  489.   int dist;
  490.   int res=0;
  491.   double angle;
  492.   double sp, spr;
  493.  
  494.   dx=x-(loadbx<<3)-2;
  495.   dy=(loadby<<3)-y+2;
  496.   dist=dx*dx+dy*dy;
  497.   if(dist<1024) {
  498.     res=1-loadcontact;
  499.   }
  500.   else if(dist>=1024 && loadcontact) {
  501.     loadcontact=0;
  502.     loaded=1;
  503.     alpha = atan2(dy, dx);
  504.     angle = atan2(speedy, speedx) - alpha;
  505.     sp=hypot(speedx, speedy);
  506.     deltaalpha=sp*sin(angle)/2 * M_PI/262144;
  507.     deltaalpha=min(deltaalpha,  M_PI/16);
  508.     deltaalpha=max(deltaalpha, -M_PI/16);
  509.     spr=sp*cos(angle);
  510.     speedx = spr*cos(alpha)/(1 + REL_MASS);
  511.     speedy = spr*sin(alpha)/(1 + REL_MASS);
  512.   }
  513.   return(res);
  514. }
  515.  
  516. int
  517. resonablefuel(int x, int y, int l)
  518. {
  519.   thing *tp;
  520.   int dx, dy;
  521.  
  522.   tp=&things[l];
  523.   dx=x-(int)(*tp).x;
  524.   dy=(int)(*tp).y-y;
  525.   if(dx>(int)(lenx3>>1))
  526.     dx=lenx3-dx;
  527.   if(-dx>(int)(lenx3>>1))
  528.     dx=-lenx3+dx;
  529.   return(dx>-10 && dx<9 && dy>5 && dy<60);
  530. }
  531.  
  532. int
  533. closestfuel(int x, int y)
  534. {
  535.   word i, which=0;
  536.   thing *thingptr;
  537.   int dx, dy;
  538.   int minimum=MAXINT, d;
  539.   int hit=0;
  540.  
  541.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  542.     if((*thingptr).type==1 && (*thingptr).alive>1) {
  543.       dx=abs((int)x-(int)(*thingptr).x);
  544.       dy=abs((int)y-(int)(*thingptr).y);
  545.       if(dx>(lenx3>>1))
  546.     dx-=lenx3;
  547.       dy*=3;
  548.       d=dx*dx+dy*dy;
  549.       if(d<minimum) {
  550.     minimum=d;
  551.     which=i;
  552.     hit=1;
  553.       }
  554.     }
  555.   return(hit?which:-1);
  556. }
  557.  
  558. int
  559. closestbutton(int x, int y)
  560. {
  561.   word i, which=0;
  562.   thing *thingptr;
  563.   int dx, dy;
  564.   int minimum=MAXINT, d;
  565.   int hit=0;
  566.  
  567.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  568.     if((*thingptr).type>=7 && (*thingptr).type<=8) {
  569.       dx=abs((int)x-(int)(*thingptr).x);
  570.       dy=abs((int)y-(int)(*thingptr).y);
  571.       if(dx>(lenx>>1))
  572.     dx-=lenx;
  573.       d=dx*dx+dy*dy;
  574.       if(d<minimum) {
  575.     minimum=d;
  576.     which=i;
  577.     hit=1;
  578.       }
  579.     }
  580.   return(hit?which:-1);
  581. }
  582.  
  583. void
  584. hit(word x, word y, word crash, word owner)
  585. {
  586.   word i, which=0;
  587.   thing *thingptr;
  588.   long dx, dy;
  589.   long minimum=MAXLONG, d;
  590.   int hit=0;
  591.   int kill=1;
  592.  
  593.   for(i=0, thingptr=things; i<nrthings; i++, thingptr++)
  594.     if((*thingptr).alive>0 && crashtype((*thingptr).type)==crash) {
  595.       dx=(int)x-(int)(*thingptr).x;
  596.       dy=(int)y-(int)(*thingptr).y;
  597.       d=(long)dx*dx+(long)dy*dy;
  598.       if(d<minimum) {
  599.     minimum=d;
  600.     which=i;
  601.     hit=1;
  602.       }
  603.     }
  604.   if(hit) {
  605. #ifdef HAVE_SOUND
  606.     if(play_sound)
  607.       Snd_effect(SND_BOOM2, CHAN_4);
  608. #endif
  609.     explodething(&things[which]);
  610.   }
  611.   if(things[which].alive == 1)  /* Can't kill a dying thing */
  612.     hit=0;
  613.   if(hit) {
  614.     switch(things[which].type) {
  615.     case 2:
  616.       ppblip+=10;
  617.       if(ppblip>100)
  618.     things[which].alive=1;  /* Dying */
  619.       break;
  620.     case 7:                     /* Cannot kill buttons */
  621.     case 8:
  622.       startupsliders(majorbutton(which));
  623.       break;
  624.     default:
  625.       things[which].alive=1;    /* Dying */
  626.       break;
  627.     }
  628.     if(kill) {
  629.     }
  630.     if(owner)
  631.       switch(things[which].type) {
  632.       case 1:
  633.     things[which].score=150;
  634.     break;
  635.       case 3:
  636.       case 4:
  637.       case 5:
  638.       case 6:
  639.     things[which].score=750;
  640.     break;
  641.       }
  642.   }
  643. }
  644.  
  645. void
  646. bunkerfirebullet(thing *b)
  647. {
  648.   int dir;
  649.  
  650.   dir=random()%16;
  651.   switch((*b).type) {
  652.   case 3:
  653.     dir=(dir-3)&31;
  654.     newbullet(((*b).x<<3)+14, ((*b).y<<3)-68,
  655.           32*cos(dir * M_PI/16), 32*sin(dir * M_PI/16),
  656.           dir>>1, 0);
  657.     break;
  658.   case 4:
  659.     dir=(dir+3)&31;
  660.     newbullet(((*b).x<<3)-26, ((*b).y<<3)-68,
  661.           32*cos(dir * M_PI/16), 32*sin(dir * M_PI/16),
  662.           dir>>1, 0);
  663.     break;
  664.   case 5:
  665.     dir=(dir-14)&31;
  666.     newbullet(((*b).x<<3)+14, ((*b).y<<3)+44,
  667.           32*cos(dir * M_PI/16), 32*sin(dir * M_PI/16),
  668.           dir>>1, 0);
  669.     break;
  670.   case 6:
  671.     dir=(dir+12)&31;
  672.     newbullet(((*b).x<<3)-26, ((*b).y<<3)+44,
  673.           32*cos(dir * M_PI/16), 32*sin(dir * M_PI/16),
  674.           dir>>1, 0);
  675.     break;
  676.   }
  677. }
  678.  
  679. void
  680. bunkerfirebullets(void)
  681. {
  682.   int l;
  683.   thing *thingptr;
  684.  
  685.   for(l=0, thingptr=things; l<nrthings; l++, thingptr++)
  686.     if((*thingptr).alive)
  687.       if((*thingptr).type>2 && (*thingptr).type<7)
  688.     if(!(random()%256))
  689.       bunkerfirebullet(thingptr);
  690. }
  691.  
  692. int
  693. killdyingthings(void)
  694. {
  695.   int l;
  696.   thing *thingptr;
  697.   int res;
  698.  
  699.   res=0;
  700.   for(l=0, thingptr=things; l<nrthings; l++, thingptr++)
  701.     if((*thingptr).alive==1) {
  702.       deletething(thingptr);
  703.       res+=(*thingptr).score;
  704.     }
  705.  
  706.   return(res);
  707. }
  708.  
  709. void
  710. killallthings(void)
  711. {
  712.   thing *thingptr;
  713.   int l;
  714.  
  715.   for(l=0, thingptr=things; l<nrthings; l++, thingptr++) {
  716.     if((*thingptr).alive > 1) {
  717.       (*thingptr).alive=1;
  718.       deletething(thingptr);
  719.       explodething(thingptr);
  720.     }
  721.   }
  722. }
  723.  
  724. void
  725. newfragment(word x, word y)
  726. {
  727.   static word nr=0;
  728.   int dir;
  729.   int speed;
  730.  
  731.   dir=random()%32;
  732.   speed=random()%48+16;
  733.   fragments[nr].life=90-speed;
  734.   fragments[nr].x=x;
  735.   fragments[nr].y=y;
  736.   fragments[nr].vx=speed*cos(dir * M_PI/16)/8;
  737.   fragments[nr++].vy=speed*sin(dir * M_PI/16)/8;
  738.  
  739.   if(nr==maxfragments)
  740.     nr=0;
  741. }
  742.  
  743. void
  744. explodething(thing *thingptr)
  745. {
  746.   int i;
  747.  
  748.   for(i=0; i<30; i++) {
  749.     newfragment((thingptr->x<<3)-30+random()%61,
  750.         (thingptr->y<<3)-30+random()%61);
  751.   }
  752. }
  753.  
  754. void
  755. explodeship(void)
  756. {
  757.   int i;
  758.  
  759.   for(i=0; i<50; i++) {
  760.     newfragment((x+((154+shipdx)<<3)+random()%61)%(lenx3<<3),
  761.         (y+(( 82+shipdy)<<3)+random()%61)%(leny3<<3));
  762.     if(loaded)
  763.       newfragment((x+((161-(int)((252-loadpoint)*cos(alpha)/7.875))<<3)
  764.            +random()%61)%(lenx3<<3),
  765.           (y+(( 89+(int)((252-loadpoint)*sin(alpha)/7.875))<<3)
  766.            +random()%61)%(leny3<<3));
  767.   }
  768. }
  769.  
  770. void
  771. movefragments(void)
  772. {
  773.   int l;
  774.   fragment *fragmentptr;
  775.  
  776.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  777.     if((*fragmentptr).life>0) {
  778.       (*fragmentptr).life--;
  779.       (*fragmentptr).x=((*fragmentptr).x+(lenx<<6)+(*fragmentptr).vx)
  780.     % (lenx<<6);
  781.       (*fragmentptr).y=((*fragmentptr).y+(leny<<6)-(*fragmentptr).vy)
  782.     % (leny<<6);
  783.     }
  784. }
  785.  
  786. word
  787. livefragments(void)
  788. {
  789.   int l;
  790.   fragment *fragmentptr;
  791.  
  792.   for(l=0, fragmentptr=&fragments[0]; l<maxfragments; l++, fragmentptr++)
  793.     if(fragmentptr->life>0)
  794.       return(1);
  795.   return(0);
  796. }
  797.